iT邦幫忙

2023 iThome 鐵人賽

DAY 4
0
自我挑戰組

Viem 介紹系列 第 7

Day 7 - Public Action (2)

  • 分享至 

  • xImage
  •  

今天來到 Public Action 第二章節介紹

watchEvent

間隔監控並且返回事件 logs

一樣以程式說明

import { http, createPublicClient, stringify } from 'viem';
import { mainnet } from 'viem/chains';

const client = createPublicClient({
	chain: mainnet,
	transport: http(),
});

// TODO: convert to `parseAbiItem`.
const event = {
	inputs: [
		{
			indexed: true,
			name: 'from',
			type: 'address',
		},
		{
			indexed: true,
			name: 'to',
			type: 'address',
		},
		{
			indexed: false,
			name: 'value',
			type: 'uint256',
		},
	],
	name: 'Transfer',
	type: 'event',
};

client.watchEvent({
	address: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
	event,
	// poll:false // 是否為 webstocket
    // args: {
    //     from:0xd8da6bf26964af9d7eed9e03e53415d37aa96045
    //     to:
    // }
	// pollingInterval: 1_000, // 每 1 秒觀察一次,如果沒有設定看 RpcServer 自己預設是多少
	onLogs: (logs) => {
		console.log(logs[0].blockNumber);
		console.log(stringify(logs, null, 2));
	},
});

這裡的範例是監控 USDT 的 Transfer 的事件。要使用args 只有在屬性有設定 indexed 才可以使控制喔!!

有一個誤區要先記得 pollingInterval 不管你有沒有設定他的觸發就是每隔多久找一次,而不是發生 event 它就呈現…

另外還有 poll 這屬性是判定是否為 webstocket 有什麼不同呢?

如果是 true 其實他就會通過 eth_subscribe 去訂閱,用這樣的方法就會是觸發 event 就會回覆。

程式實作:
https://github.com/0xRory/ITHepleViem/blob/main/examples/3_5_publicAction_WatchEvent.js

verifyMessage

驗證所提供的地址是否簽署

此操作支持驗證由智慧合約帳戶或外部擁有的帳戶簽名的消息。該 verifyMessage 實用程式僅支援外部擁有的帳戶。隨著越來越多的錢包實現帳戶抽象,這一點變得越來越重要。

這段我用程式說明作法

import { createPublicClient, http, createWalletClient, custom } from 'viem';
import { mainnet } from 'viem/chains';

const publicClient = createPublicClient({
	chain: mainnet,
	transport: http(),
}); // 建立 Client

const walletClient = createWalletClient({
  transport: custom(window.ethereum)
}) 

// JSON-RPC Account
const [account] = await walletClient.getAddresses() //從建立錢包中給帳號
// Local Account
const account = privateKeyToAccount(...) // 或是你使用本地建立錢包...(請注意這裡是私鑰)

// 建立 sign 請記得如果要使用這個話一定要連接錢包並使用(私鑰)
const signature = await walletClient.signMessage({
     account,
     message: 'hello world',
   })
// 這裡給一個簡單的範例示意
const valid = await publicClient.verifyMessage({
	address: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266',
	message: 'hello world',
	signature:
		'0x66edc32e2ab001213321ab7d959a2207fcef5190cc9abb6da5b0d2a8a9af2d4d2b0700e2c317c4106f337fd934fbbb0bf62efc8811a78603b33a8265d3b8f8cb1c',
});

console.log('valid', valid);

就如前面所說這樣的,這個簽章是使用你的私鑰所建立的那代表如果你有signature 和 Address 你就可以確認這是你專屬的,這樣使用的話對於是不是這件事情就比較好判定了。

verifyTypedData 驗證類型數據

此操作支持驗證由智慧合約帳戶或外部擁有帳戶(通過ERC-6492)簽名的類型數據。該 verifyTypedData 實用程式僅支援外部擁有的帳戶。隨著越來越多的錢包實現帳戶抽象,這一點變得越來越重要。

先看一下程式碼:

import { createPublicClient, http, createWalletClient, custom } from 'viem';
import { mainnet } from 'viem/chains';

const publicClient = createPublicClient({
	chain: mainnet,
	transport: http(),
}); // 建立 Client

const walletClient = createWalletClient({
  transport: custom(window.ethereum)
}) 

// JSON-RPC Account
const [account] = await walletClient.getAddresses() //從建立錢包中給帳號
// Local Account
const account = privateKeyToAccount(...) // 或是你使用本地建立錢包...(請注意這裡是私鑰)
// 類別
const domain = { 
  name: 'Ether Mail',
  version: '1',
  chainId: 1,
  verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC',
}

// The named list of all type definitions
const types = {
  Person: [
    { name: 'name', type: 'string' },
    { name: 'wallet', type: 'address' },
  ],
  Mail: [
    { name: 'from', type: 'Person' },
    { name: 'to', type: 'Person' },
    { name: 'contents', type: 'string' },
  ],
}
// 訊息從 cow -> Bob 來的訊息 Hello, Bob!
const message = {
  from: {
    name: 'Cow',
    wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826',
  },
  to: {
    name: 'Bob',
    wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB',
  },
  contents: 'Hello, Bob!',
}

const signature = await walletClient.signTypedData({
  account,
  domain,
  types,
  primaryType: 'Mail',
  message,
})

// 驗證定義類型資料
const valid = await publicClient.verifyTypedData({
  address: account.address,
  domain,
  types,
  primaryType: 'Mail',
  message,
  signature,
})

這比較難我試著說明看看,簡單來說就是一般的驗證都是單一的,沒有什麼類別,但是如果有了domain 代表驗證是會有類別,有設定的合約。這樣就可以有很多應用了,你可以鏈上驗證+線下驗證做你要的機制。

程式實作:
https://github.com/0xRory/ITHepleViem/blob/main/examples/3_6_verifyMessage.js

參考:
https://viem.sh/docs/actions/public/watchEvent.html
https://viem.sh/docs/actions/public/verifyMessage.html
https://viem.sh/docs/actions/public/verifyTypedData.html


上一篇
Day 6 - Public Action (1)
下一篇
Day 8 - Transaction (1)
系列文
Viem 介紹11
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言